﻿/*
  --============================================================================================
  --============================================================================================
  -- Fichier          :	IterateurDetailPV.cs
  -- Objet			  :	Permet d'itérer une liste de détails et de sortir dans le bon ordre pour générer le PV. (Pattern Iterator)
  -- Auteur			  :	S. Le Gouellec
  -- Date de création : 07/2014
  --                              :
  --                              :
  -- Notes spéciales		  :
  -- Historique			  :
  ----------------------------------------------------------------------------------------------
  -- |     Code    |  Vers. |   Date   | Auteur	|                  Description
  -- |  Dem/inc/pr |  	    |          |        |         
  -- -------------------------------------------------------------------------------------------
  -- |             |   1.0  | 07/2014  |  SLE	| Création
  -- |	           |	    |	       |        |
  --============================================================================================
  --============================================================================================
*/

using ModelEntities.Adapter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Models.ExportPV
{
    /// <summary>
    /// 
    /// </summary>
    public class IterateurDetailPV : Iterateur
    {
        #region Attribut(s)

        /// <summary>
        /// Position Courante du Curseur pour le code instruction à retourner
        /// </summary>
        private int positionCursor = -1;

        /// <summary>
        /// Numéro de la page courante du PV
        /// </summary>
        private int numeroPage = 1;

        /// <summary>
        /// Nombre total de pages de ce PV
        /// </summary>
        private int nbrPage;

        #endregion

        #region Propriété(s)

        /// <summary>
        /// Liste des Codes instructions à exporter
        /// </summary>
        private List<String> Headers
        {
            get;
            set;
        }

        #endregion

        #region Constructeur(s)

        /// <summary>
        /// Constructeur avec la liste de données en paramètre
        /// </summary>
        /// <param name="l">Liste de données à itérer</param>
        public IterateurDetailPV(Liste l)
        {
            ListData = l;
            nbrPage = (ListData as ListeDetailsPV).Details.Max<MDetailsPV>(detail => Convert.ToInt32(detail.NoPage));
            InitHeader();
        }

        #endregion

        #region Méthode(s)

        /// <summary>
        /// Permet d'initialiser les codes instructions qui vont être exporter dans le nouveau pv généré.
        /// </summary>
        private void InitHeader()
        {
            Headers = new List<String>();
            Headers.Add("STRE/  ");
            Headers.Add("OF01/01");
            Headers.Add("OF01/02");
            Headers.Add("OF01/03");
            Headers.Add("OF01/04");
            Headers.Add("OF01/05");
            Headers.Add("OF01/06");
            Headers.Add("OF01/07");
            Headers.Add("OF01/08");
            Headers.Add("OF01/09");
            Headers.Add("OF01/10");
            Headers.Add("OF01/11");
            Headers.Add("OF01/12");
            Headers.Add("OF01/13");
            Headers.Add("OF01/14");
            Headers.Add("OF01/15");
            Headers.Add("OF01/16");
            Headers.Add("OF01/17");
            Headers.Add("OF01/18");
            Headers.Add("OF01/19");
            Headers.Add("OF01/20");
            Headers.Add("OF01/21");
            Headers.Add("OF01/22");
            Headers.Add("OF01/23");
            Headers.Add("OF01/24");
            Headers.Add("OF01/25");
            Headers.Add("EA01/01");
            Headers.Add("RE01/01");
            Headers.Add("EJ02/02");
            Headers.Add("EB01/01");
            Headers.Add("EC01/01");
            Headers.Add("EC02/02");
            Headers.Add("EC03/03");
            Headers.Add("ED01/01");
            Headers.Add("ED02/02");
            Headers.Add("ED03/03");
            Headers.Add("ED04/04");
            Headers.Add("ED05/05");
            Headers.Add("ED06/06");
            Headers.Add("EE01/01");
            Headers.Add("EE02/01");
            Headers.Add("EF01/01");
            Headers.Add("EG01/01");
            Headers.Add("EG02/02");
            Headers.Add("EG03/03");
            Headers.Add("EG04/04");
            Headers.Add("EG05/05");
            Headers.Add("EG06/06");
            Headers.Add("EG07/07");
            Headers.Add("EH01/01");
            Headers.Add("EH02/02");
            Headers.Add("EH03/03");
            Headers.Add("EH04/04");
            Headers.Add("EH05/05");
            Headers.Add("EH06/06");
            Headers.Add("EH07/07");
            Headers.Add("EZ01/01");
            Headers.Add("AZ01/01");
            Headers.Add("NC01/01");
            Headers.Add("OR01/01");
            Headers.Add("OR02/02");
            Headers.Add("OR03/03");
            Headers.Add("OR04/04");
            Headers.Add("EI01/01");
            Headers.Add("PI01/01");
            Headers.Add("DR01/01");
            Headers.Add("DR01/02");
            Headers.Add("DR01/03");
            Headers.Add("DR01/04");
            Headers.Add("DR01/05");
            Headers.Add("DR01/06");
            Headers.Add("DR01/07");
            Headers.Add("DR01/08");
            Headers.Add("DR01/09");
            Headers.Add("DR01/10");
            Headers.Add("DR01/11");
            Headers.Add("DR01/12");
            Headers.Add("DR01/13");
            Headers.Add("DR01/14");
            Headers.Add("DR01/15");
            Headers.Add("DR01/16");
            Headers.Add("DR01/17");
            Headers.Add("EM01/01");
            Headers.Add("EN01/01");
            Headers.Add("EO01/01");
            Headers.Add("ES01/01");
            Headers.Add("ET01/01");
            Headers.Add("EU01/01");
            Headers.Add("EP01/01");
            Headers.Add("EQ01/01");
            Headers.Add("EV01/01");
            Headers.Add("EW01/01");
            Headers.Add("EX01/01");
            Headers.Add("DE01/01");
            Headers.Add("DC01/01");
            Headers.Add("DC01/02");
            Headers.Add("DC01/03");
            Headers.Add("DC01/04");
            Headers.Add("DC01/05");
            Headers.Add("DP01/01");
            Headers.Add("PB01/01");
            Headers.Add("PB02/02");
            Headers.Add("PG01/01");
            Headers.Add("PG02/02");
            Headers.Add("PG03/03");
            Headers.Add("PG04/04");
            Headers.Add("PG05/05");
            Headers.Add("PG06/06");
            Headers.Add("PG07/07");
            Headers.Add("PA01/01");
            Headers.Add("PA02/02");
            Headers.Add("PA03/03");
            Headers.Add("PA04/04");
            Headers.Add("PA05/05");
            Headers.Add("PA06/06");
            Headers.Add("PA07/07");
            Headers.Add("PA08/08");
            Headers.Add("PA09/09");
            Headers.Add("PA10/10");
            Headers.Add("PA11/11");
            Headers.Add("PA12/12");
            Headers.Add("PD01/01");
            Headers.Add("PD02/02");
            Headers.Add("PD03/03");
            Headers.Add("PD04/04");
            Headers.Add("PD05/05");
            Headers.Add("PD06/06");
            Headers.Add("PD07/07");
            Headers.Add("PD08/08");
            Headers.Add("PD09/09");
            Headers.Add("PD10/10");
            Headers.Add("PD11/11");
            Headers.Add("PD12/12");
            Headers.Add("PE01/01");
            Headers.Add("PF01/01");
            Headers.Add("PC01/01");
            Headers.Add("PC02/02");
            Headers.Add("PC03/03");
            Headers.Add("PC04/04");
            Headers.Add("PC05/05");
            Headers.Add("PC06/06");
            Headers.Add("PH01/01");
            Headers.Add("OL01/01");
            Headers.Add("OL02/01");
            Headers.Add("OL03/01");
            Headers.Add("OL04/01");
            Headers.Add("OL04/02");
            Headers.Add("OL04/03");
            Headers.Add("OL04/04");
            Headers.Add("OL04/05");
            Headers.Add("OL04/06");
            Headers.Add("OL04/07");
            Headers.Add("OL04/08");
            Headers.Add("OL04/09");
            Headers.Add("OL04/10");
            Headers.Add("LG01/01");
            Headers.Add("LG02/01");
            Headers.Add("LG03/01");
            Headers.Add("LG04/01");
            Headers.Add("LG05/01");
            Headers.Add("LG06/01");
            Headers.Add("LC01/01");
            Headers.Add("EL01/01");
            Headers.Add("DN01/01");
            Headers.Add("DN02/01");
            Headers.Add("SP01/01");
        }

        #endregion

        #region Implémentation Iterateur

        /// <summary>
        /// Retourne le premier élément de la liste sans se soucier du curseur actuel
        /// </summary>
        /// <returns>Retourne le premier élément de type MDetailsPV de la liste</returns>
        public object First()
        {
            return (ListData as ListeDetailsPV).Details.ElementAt<MDetailsPV>(0);
        }

        /// <summary>
        /// Incrémente de 1 le curseur et retourne l'élément
        /// </summary>
        /// <returns>Retourne le prochain élément</returns>
        public object Next()
        {
            if (positionCursor == (Headers.Count - 1))
            {
                ++numeroPage;
                positionCursor = 0;
            }
            else
                ++positionCursor;

            return CurrentElement;
        }

        /// <summary>
        /// Retourne true si l'itération est finie ou false
        /// </summary>
        /// <returns></returns>
        public bool Finish()
        {
            return (((positionCursor + 1) * numeroPage) == (Headers.Count * nbrPage));
        }

        /// <summary>
        /// Retourne l'élément courant
        /// </summary>
        public object CurrentElement
        {
            get 
            {
                if (positionCursor >= 0)
                {
                    String header = Headers.ElementAt(positionCursor);
                    String codeInstruction = header.Split(new string[] { "/" }, StringSplitOptions.None)[0];
                    String numLigne = header.Split(new string[] { "/" }, StringSplitOptions.None)[1];

                    try
                    {
                        return (ListData as ListeDetailsPV).Details.First<MDetailsPV>(detail => detail.CodeInstruction.Equals(codeInstruction) && detail.NoLigne.Equals(numLigne) && Convert.ToInt32(detail.NoPage) == numeroPage);
                    }catch(InvalidOperationException)
                    {
                        MDetailsPV mDet = new MDetailsPV();
                        mDet.CodeInstruction = codeInstruction;
                        mDet.NoLigne = numLigne;
                        mDet.LibelleInstruction = String.Empty;
                        return mDet;
                    }
                }
                else
                    return null;
            }
        }

        /// <summary>
        /// Liste de données à itérer
        /// </summary>
        public Liste ListData
        {
            get;
            set;
        }

        #endregion
    }
}
